package com.caiden_micheal.org.service.impl;


import com.caiden_micheal.base.constant.LoggerHead;
import com.caiden_micheal.base.domain.AjxResult;
import com.caiden_micheal.base.dto.PageDTO;
import com.caiden_micheal.menu.utils.MenuUtil;
import com.caiden_micheal.base.utils.RedisUtil;
import com.caiden_micheal.base.vo.PageVo;
import com.caiden_micheal.menu.service.MenuService;
import com.caiden_micheal.org.domain.Org;
import com.caiden_micheal.org.domain.OrgAuthority;
import com.caiden_micheal.org.dto.OrgSelectDTO;
import com.caiden_micheal.org.mapper.OrgMapper;
import com.caiden_micheal.org.vo.*;
import com.caiden_micheal.permission.domain.Permission;
import com.caiden_micheal.permission.mapper.PermissionMapper;
import com.caiden_micheal.permission.service.PermissionService;
import com.caiden_micheal.position.domain.Position;
import com.caiden_micheal.user.domain.PositionOrgUser;
import com.caiden_micheal.user.domain.User;
import com.caiden_micheal.user.domain.UserAuthority;
import com.caiden_micheal.user.mapper.OrgAuthorityMapper;
import com.caiden_micheal.org.service.OrgService;
import com.caiden_micheal.user.mapper.PositionOrgUserMapper;
import com.caiden_micheal.user.mapper.UserMapper;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.ArrayList;
import java.util.List;

@Service
public class OrgServiceImpl implements OrgService {
    private static final Logger logger = LoggerFactory.getLogger(OrgServiceImpl.class);

    @Autowired
    private OrgAuthorityMapper orgAuthorityMapper;
    @Autowired
    private OrgMapper orgMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private PermissionService permissionService;
    @Autowired
    private PermissionMapper permissionMapper;
    @Autowired
    private PositionOrgUserMapper positionOrgUserMapper;
    @Lazy
    @Autowired
    private MenuService menuService;

    @Override
    public List<UserAuthority> findOrgAuthorityListById(Long id) {
        return orgAuthorityMapper.findOrgAuthorityListById(id);
    }

    @Override
    public PageDTO findOrgsByCondition(OrgQueryVO orgQueryVO) {
        PageVo page = orgQueryVO.getPage();
        if (page == null) {
            logger.warn(LoggerHead.warnHead() + "orgQueryVO.page is Null!");
            return null;
        }
        page.setCurrentIndex((long) (page.getCurrentPage() - 1) * page.getPageSize());
        List<Org> orgList = orgMapper.findOrgListPaginationQuery(orgQueryVO);
        page.setCount(orgMapper.findOrgListQueryCount(orgQueryVO));
        return new PageDTO(orgList, page);
    }

    @Override
    public PageDTO findOrgsByConditionPermission(OrgQueryVO orgQueryVO) {
        PageVo page = orgQueryVO.getPage();
        if (page == null) {
            logger.warn(LoggerHead.warnHead() + "orgQueryVO.page is Null!");
            return null;
        }
        page.setCurrentIndex((long) (page.getCurrentPage() - 1) * page.getPageSize());
        List<Long> orgIdList = orgAuthorityMapper.findOrgIdsByAuthorityId(orgQueryVO.getPermissionId());
        if (orgIdList == null || orgIdList.size() == 0) {
            return null;
        }
        List<Org> orgList = orgMapper.findByIdList(orgIdList, orgQueryVO);
        page.setCount(orgMapper.findOrgCountByOrgIds(orgIdList, orgQueryVO));
        return new PageDTO(orgList, page);
    }

    @Override
    public List<OrgSelectDTO> findOrgSelectDatas() {
        return orgMapper.findOrgSelectDatas();
    }

    @Override
    public AjxResult addOrg(Org org) {
        Org data = orgMapper.findByName(org.getOrgName());
        if (data == null) {
            orgMapper.addOrg(org);
            return AjxResult.success("创建成功");
        } else {
            return AjxResult.repetitiveError("部门名称已存在");
        }
    }

    @Transactional
    @Override
    public AjxResult editOrg(Org org) {
        Org data = orgMapper.findById(org.getId());
        if (data == null) {
            return AjxResult.unknownError("未找到此记录");
        }
        try {
            if (!StringUtils.equals(data.getOrgName(), org.getOrgName())) {
                if (orgMapper.findByName(org.getOrgName()) != null) {
                    return AjxResult.repetitiveError("部门名称已存在");
                }
                orgMapper.update(org);
                OrgAuthority orgAuthority = new OrgAuthority();
                orgAuthority.setOrgName(org.getOrgName());
                orgAuthority.setOrgId(org.getId());
                orgAuthorityMapper.updateByOrgId(orgAuthority);
                userMapper.updateOrgName(org.getOrgName(), org.getId());
                PositionOrgUser positionOrgUser = new PositionOrgUser();
                positionOrgUser.setOrgId(org.getId());
                positionOrgUser.setOrgName(org.getOrgName());
                positionOrgUserMapper.update(positionOrgUser);
            } else {
                orgMapper.update(org);
            }
            return AjxResult.success("修改成功");
        } catch (Exception e) {
            logger.error(e.toString());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjxResult.unknownError("数据库操作异常");
        }
    }

    @Transactional
    @Override
    public AjxResult updateOrgUser(OrgAddUserVO orgAddUserVO) {
        Org org = orgMapper.findById(orgAddUserVO.getOrgId());
        try {
            if (org != null) {
                userMapper.updateUserOrgByIds(orgAddUserVO.getUserIdList(), org);
                Org tempOrg = new Org();
                tempOrg.setId(orgAddUserVO.getOrgId());
                tempOrg.setUserCount(org.getUserCount() + orgAddUserVO.getUserIdList().size());
                orgMapper.update(tempOrg);
            } else {
                return AjxResult.paramError("未找到该部门");
            }
            return AjxResult.success("修改成功");
        } catch (Exception e) {
            logger.error(e.toString());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjxResult.unknownError("数据库操作异常");
        }
    }

    @Transactional
    @Override
    public AjxResult removeUser(Long userId) {
        if (userId == null) {
            return AjxResult.paramError("入参用户为空");
        }
        try {
            User tempUser = new User();
            tempUser.setId(userId);
            User user = userMapper.findOne(tempUser);
            if (user == null) {
                return AjxResult.paramError("传入的用户不存在");
            }
            Long orgId = user.getOrgId();
            Org org = orgMapper.findById(orgId);
            if (org == null) {
                return AjxResult.paramError("用户当前所在部门为空");
            }
            Org tempOrg = new Org();
            tempOrg.setUserCount(org.getUserCount() - 1);
            tempOrg.setId(orgId);
            orgMapper.update(tempOrg);
            ArrayList<Long> userIds = new ArrayList<>();
            userIds.add(userId);
            userMapper.updateUserOrgByIds(userIds, new Org());
            RedisUtil.deleteFold("caiden_micheal:user:" + userId + ":*");
            return AjxResult.success("删除成功");
        } catch (Exception e) {
            logger.error(e.toString());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjxResult.unknownError("数据库操作异常");
        }
    }

    @Override
    public PageDTO excludePermission(OrgQueryVO orgQueryVO) {
        PageVo page = orgQueryVO.getPage();
        if (page == null) {
            logger.warn(LoggerHead.warnHead() + "orgQueryVO.page is Null!");
            return null;
        }
        page.setCurrentIndex((long) (page.getCurrentPage() - 1) * page.getPageSize());
        List<Long> orgIdList = orgAuthorityMapper.findOrgIdsByAuthorityId(orgQueryVO.getPermissionId());
        if (orgIdList.size() == 0) {
            orgIdList = null;
        }
        List<Org> orgList = orgMapper.findByExcludeOrgIdList(orgIdList, orgQueryVO);
        Integer count = orgMapper.findByExcludeOrgIdListCount(orgIdList, orgQueryVO);
        page.setCount(count);
        return new PageDTO(orgList, page);
    }

    @Transactional
    @Override
    public AjxResult orgPermissionAssignment(OrgPermissionAssignmentVO orgPermissionAssignmentVO) {
        if (orgPermissionAssignmentVO == null || orgPermissionAssignmentVO.getOrgIds() == null || orgPermissionAssignmentVO.getPermissionId() == null) {
            return AjxResult.paramError("非法参数传入，已记录当前请求IP行为，警告不要胡来");
        }
        List<Org> orgList = orgMapper.findAllOrgByIdList(orgPermissionAssignmentVO.getOrgIds());
        Permission permission = permissionService.findById(orgPermissionAssignmentVO.getPermissionId());
        try {
            List<Permission> permissionList = new ArrayList<>();
            permissionList.add(permission);
            MenuUtil.permissionListMerging(permissionList, menuService);
            for (Permission permissionInner : permissionList) {
                orgList = excludeExistOrg(orgList, permissionInner);
                if (orgList.size() == 0) {
                    break;
                }
                orgMapper.addOrgPermissionByOrgIds(orgList, permissionInner);
                Permission tempPermission = new Permission();
                tempPermission.setId(permissionInner.getId());
                tempPermission.setOrgCount(permissionInner.getOrgCount() + orgList.size());
                permissionMapper.update(tempPermission);
            }
            return AjxResult.success("机构权限更新成功");
        } catch (Exception e) {
            logger.error(e.toString());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjxResult.unknownError("操作数据库失败");
        }
    }

    private List<Org> excludeExistOrg(List<Org> orgList, Permission permissionInner) {
        List<Long> existIdList = orgAuthorityMapper.findOrgIdsByAuthorityId(permissionInner.getId());
        ArrayList<Org> tempOrgList = new ArrayList<>();
        for (Org org : orgList) {
            if (!existIdList.contains(org.getId())) {
                tempOrgList.add(org);
            }
        }
        return tempOrgList;
    }

    @Transactional
    @Override
    public AjxResult orgPermissionRemove(OrgPermissionRemoveVO orgPermissionRemoveVO) {
        try {
            Org tempOrg = orgMapper.findById(orgPermissionRemoveVO.getOrgId());
            if (tempOrg == null) {
                return AjxResult.paramError("部门不存在");
            }
            Permission permission = permissionMapper.findById(orgPermissionRemoveVO.getAuthorityId());
            if (permission == null) {
                return AjxResult.paramError("权限不存在");
            }
            List<Permission> permissionList = MenuUtil.permissionRemoveListMerging(permission, menuService);
            List<Long> permissionIncludeIdList = orgAuthorityMapper.findAuthorityIdsByOrgId(tempOrg.getId());
            permissionList = MenuUtil.extractIncludeRemove(permissionIncludeIdList, permissionList);
            for (Permission permissionInner : permissionList) {
                orgAuthorityMapper.deleteAuthority(tempOrg.getId(), permissionInner.getId());
                Permission tempPermission = new Permission();
                tempPermission.setId(permissionInner.getId());
                tempPermission.setOrgCount(permissionInner.getOrgCount() - 1);
                permissionMapper.update(tempPermission);
            }
            return AjxResult.success("移除成功");
        } catch (Exception e) {
            logger.error(e.toString());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjxResult.unknownError("数据库操作异常");
        }
    }

    @Override
    public AjxResult orgQuerySelectByPosition(Position position) {
        if (position == null || position.getId() == null) {
            return AjxResult.paramError("参数传入有误");
        } else {
            try {
                List<PositionOrgUser> positionOrgUserList = positionOrgUserMapper.findByPositionId(position.getId());
                if (positionOrgUserList == null || positionOrgUserList.size() == 0) {
                    return AjxResult.success(orgMapper.findOrgSelectDatas());
                }
                List<Long> orgIdList = new ArrayList<>();
                for (PositionOrgUser positionOrgUser : positionOrgUserList) {
                    orgIdList.add(positionOrgUser.getOrgId());
                }
                return AjxResult.success(orgMapper.findSelectByExcludeOrgIdList(orgIdList));
            } catch (Exception e) {
                logger.error(e.toString());
                return AjxResult.unknownError("数据库操作异常");
            }
        }
    }

    @Transactional
    @Override
    public AjxResult orgAddPermission(OrgAddPermissionVO orgAddPermissionVO) {
        if (orgAddPermissionVO == null || orgAddPermissionVO.getAuthorityIds() == null || orgAddPermissionVO.getOrgId() == null) {
            return AjxResult.paramError("参数传入错误");
        }
        Org org = orgMapper.findById(orgAddPermissionVO.getOrgId());
        if (org == null) {
            return AjxResult.paramError("职位不存在");
        }
        List<Permission> permissionList = permissionMapper.findBatchByIds(orgAddPermissionVO.getAuthorityIds());
        if (permissionList == null) {
            return AjxResult.paramError("权限均不存在");
        }
        try {
            MenuUtil.permissionListMerging(permissionList, menuService);
            List<Long> existsPermissionIdList = orgAuthorityMapper.findAuthorityIdsByOrgId(org.getId());
            permissionList = MenuUtil.excludeExistPermission(existsPermissionIdList, permissionList);
            orgAuthorityMapper.batchAddByAuthorityListAndPosition(permissionList, org);
            List<Long> permissionIdList = new ArrayList<>();
            for (Permission permission : permissionList) {
                permissionIdList.add(permission.getId());
            }
            permissionMapper.updateOrgCountByIds(permissionIdList, true);
            return AjxResult.success("添加成功");
        } catch (Exception e) {
            logger.error(e.toString());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjxResult.unknownError("数据库操作异常");
        }
    }

    @Transactional
    @Override
    public AjxResult orgRemoveAuthority(OrgPermissionRemoveVO orgPermissionRemoveVO) {
        if (orgPermissionRemoveVO == null || orgPermissionRemoveVO.getAuthorityId() == null || orgPermissionRemoveVO.getOrgId() == null) {
            return AjxResult.paramError("参数传入有误");
        }
        Org org = orgMapper.findById(orgPermissionRemoveVO.getOrgId());
        if (org == null) {
            return AjxResult.paramError("机构不存在");
        }
        Permission tempPermission = permissionMapper.findById(orgPermissionRemoveVO.getAuthorityId());
        if (tempPermission == null) {
            return AjxResult.paramError("权限不存在");
        }
        try {
            List<Permission> permissionList = MenuUtil.permissionRemoveListMerging(tempPermission, menuService);
            List<Long> permissionIncludeIdList = orgAuthorityMapper.findAuthorityIdsByOrgId(org.getId());
            permissionList = MenuUtil.extractIncludeRemove(permissionIncludeIdList, permissionList);
            for (Permission permissionInner : permissionList) {
                orgAuthorityMapper.deleteAuthority(org.getId(), permissionInner.getId());
                Permission permission = new Permission();
                permission.setId(permissionInner.getId());
                permission.setOrgCount(permissionInner.getOrgCount() - 1);
                permissionMapper.update(permission);
            }
            // 查找所有所在部门人员，清楚redis强制重新登录
            List<Long> userIdList = userMapper.findUserIdsByOrgId(orgPermissionRemoveVO.getOrgId());
            for (Long id : userIdList) {
                RedisUtil.deleteFold("caiden_micheal:user:" + id + ":*");
            }
            return AjxResult.success("移除成功");
        } catch (Exception e) {
            logger.error(e.toString());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjxResult.unknownError("数据库操作异常");
        }
    }

    @Override
    public List<UserAuthority> findOrgAuthorityListByIds(List<Long> orgIdList) {
        if (orgIdList == null || orgIdList.size() == 0) {
            return new ArrayList<>();
        }
        return orgAuthorityMapper.findAuthoritysByOrgIds(orgIdList);
    }

    @Override
    public AjxResult findOrgTree() {
        // 递归查询org树状结构
        List<Org> parentOrgList = orgMapper.findByParentId(0L);
        List<Org> orgList = recursiveQueryOrg(parentOrgList);
        return AjxResult.success(orgList);
    }

    private List<Org> recursiveQueryOrg(List<Org> orgList) {
        for (Org org : orgList) {
            List<Org> childOrgList = orgMapper.findByParentId(org.getId());
            if (childOrgList != null && childOrgList.size() != 0) {
                List<Org> endChildList = recursiveQueryOrg(childOrgList);
                org.setChild(endChildList);
            }
        }
        return orgList;
    }
}
